/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package researchgrants.parts.GrantRequest.perennialStipends;

import java.awt.BorderLayout;
import javax.swing.event.ChangeEvent;
import researchgrants.parts.LoggedData.panels.events.SaveValidationEvent;
import researchgrants.parts.panels.*;
import java.awt.Component;
import java.awt.FlowLayout;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import researchgrants.parts.LoggedData.panels.LoggedDataPanelsNumber;
import javax.swing.event.ChangeListener;
import researchgrants.parts.LoggedData.panels.events.SaveValidationListener;
import researchgrants.parts.db.Db;
import researchgrants.parts.panelsManager.CompoundDataPanelsManager;
import researchgrants.parts.panelsManager.LoggedDataPanelsManager;
import researchgrants.utils.MyDialog;

/**
 * A compound panel to display and edit Perennial Stipends, which is a field (expectedPerennialStipends) in GrantRequest and a field (actualPerennialStipends) in GrantRequestStatusChangeAwarded.
 * This component is made of a year editable field, and a repeating (as the number of years) DirectMoney and IndirectMoney fields which are encompassed in PanelsStipend.
 * 
 * Two majorly different behaviors occur:
 * If a new PerennialStipends: All panels are initialized with defaults. Upon changes within any inner panel (year, yearly' panel, components within yearly' panels), global changes occur (validation for allowing or disallowing save, resizing years). Then when save occurs (when everything is valid only), this panel saves first and later all yearly panels save.
 * If an existing PerennialStipends: All panels are initialized with the previously saved values. The years' panels are resized upon change to the year field. Saving occurs independendtly for each field.
 * @author DOStudent1
 */
public class PanelsPerennialStipends extends PanelsCompoundView {


    // a reference to PerennialStipends.
    // Can be initialized for editing an existing PerennialStipends be uninitialized for a new PerennialStipends.
    private PerennialStipends perennialStipends=null;
    private boolean isDataInitialized=false;


    // The default values will be used when initially displayed
    private int defaultYears=1;
    private Long[] defaultDirectMoney=new Long[1];
    private Long[] defaultIndirectMoney=new Long[1] ;

    // a global-style components
    private JPanel pnlContent=new JPanel(new BorderLayout(0, 0));
    private JPanel pnlStipends=new JPanel();
    private LoggedDataPanelsManager yearsView;
    private LoggedDataPanelsNumber yearsPanel;
    private PanelsStipend[] panelsPerennialStipends;
    
    // can set the default data of the panels using an existing PerennialStipends
    // Used to prepopulate the actualPerennialStipends with the expectedPerennialStipends
    public void setDefaultData(PerennialStipends original) {
        String currentYears=original.getCurrentYears();
        if ((currentYears!=null) && (!currentYears.equals(""))) {
            defaultYears=Integer.parseInt(original.getCurrentYears());
            Stipend[] originalStipends=original.getStipends();
            defaultDirectMoney=new Long[originalStipends.length];
            defaultIndirectMoney=new Long[originalStipends.length];
            for (int i = 0; i < originalStipends.length; i++) {
                Stipend stipend = originalStipends[i];
                if (stipend.getCurrentDirectMoney()==null) {
                    defaultDirectMoney[i]=null;
                } else {
                    if (stipend.getCurrentDirectMoney().equals("")) {
                        defaultDirectMoney[i]=null;
                    } else {
                        defaultDirectMoney[i]=Long.parseLong(stipend.getCurrentDirectMoney());
                    }
                }
                if (stipend.getCurrentIndirectMoney()==null) {
                    defaultIndirectMoney[i]=null;
                } else {
                    if (stipend.getCurrentIndirectMoney().equals("")) {
                        defaultIndirectMoney[i]=null;
                    } else {
                        defaultIndirectMoney[i]=Long.parseLong(stipend.getCurrentIndirectMoney());
                    }
                }
            }
        }
    }
    
    // set this panels to an existing PerennialStipends
    public void setData(PerennialStipends perennialStipends) {
        this.perennialStipends=perennialStipends;
        isDataInitialized=true;
    }
    
    // Gets the panel to display and edit the PerennialStipends
    @Override
    public Component getComponent() {
        redrawContent();
        return(pnlContent);
    }

    // puts the entire content 
    private void redrawContent() {
        pnlContent.removeAll();

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        // Create the years panel and listen to it for to change the rest of the content in accroding to it
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        JPanel pnlYears=new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        pnlYears.add(new JLabel("Years:"));
        yearsPanel=new LoggedDataPanelsNumber(true, 1, true, 20);
        if (isDataInitialized) {
            // if this is an existing PerennialStipends, listen to saved changes to resize the years' panels
            // So, when you change the years and save, the corresponding yearly amounts are actually created as well.
            yearsPanel.setData(perennialStipends.getLoggedDataYears());
            yearsPanel.addSaveValidationListener(new SaveValidationListener() {
                public void saveValidationSaved(SaveValidationEvent e) {
                    // if saved a new year count, resize the years (into the database) in accordance.
                    if (yearsPanel.getEdittedValue().equals("")) {
                        // a blank value - no years should be displayed
                        perennialStipends.setYears(0);
                    } else {
                        // resize the years to the new value entered
                        perennialStipends.setYears(Integer.parseInt(yearsPanel.getEdittedValue()));
                    }
                    // and then redraw the entire content from what is in the database
                    redrawContent();
                }
            });
        } else {
            // if this is a new PerennialStipends, listen to changes to resize the years' panels
            // This because you can't save parts. Instead, you save everything when the user press the save button
            yearsPanel.setDefaultValue(Integer.toString(defaultYears));
            yearsPanel.addChangeListener(new ChangeListener() {

                public void stateChanged(ChangeEvent e) {
                    readjustDefaultValues();
                    // the years field had changed, just redraw the years' panels
                    redrawStipendsContent();
                    notifyAllChangeListeners(new ChangeEvent(this));
                }
            });
        }
        
        yearsPanel.setParent(getParentWindow(), getParentContainer());

        // wraps the years with a manager to allow to save
        yearsView=new LoggedDataPanelsManager();
        yearsPanel.addChangeListener(yearsView);
        yearsView.startAsNew(!isDataInitialized);
        yearsView.setMandatory(false);
        yearsView.setPanels(yearsPanel);
        pnlYears.add(yearsView);
        yearsView.display();
        pnlContent.add(pnlYears, BorderLayout.NORTH);

        // creates the yearly stipends
        redrawStipendsContent();
        pnlContent.add(pnlStipends, BorderLayout.CENTER);
    }
    
    // redraw the yearly amounts' panels
    private void redrawStipendsContent() {
        pnlStipends.removeAll();
        pnlStipends.setLayout(new BoxLayout(pnlStipends, BoxLayout.Y_AXIS));

        // initialize the amount of years
        int requestedYears;
        if (isDataInitialized) {
            //  initialize the years from the saved value
            requestedYears=perennialStipends.getStipends().length;
        } else {
            // initialize the years from the requested default
            requestedYears=defaultDirectMoney.length;
        }
        
        panelsPerennialStipends=new PanelsStipend[requestedYears];
        for (int i=0;i<requestedYears;i++) {
            // create a PanelsStipend for each year
            PanelsStipend panelsStipend=new PanelsStipend();
            panelsPerennialStipends[i]=panelsStipend;
            // load this year's values
            if (isDataInitialized) {
                // from the database
                panelsStipend.setData(perennialStipends.getStipends()[i]);
            } else {
                // from the defaults requested
                panelsStipend.setDefaultValue(i+1, defaultDirectMoney[i], defaultIndirectMoney[i]);
                // if a new PerennialStipends, listen to changes to validate
                panelsStipend.addChangeListener(new ChangeListener() {

                    public void stateChanged(ChangeEvent e) {
                        notifyAllChangeListeners(new ChangeEvent(this));
                    }
                });
            }
            panelsStipend.setParent(getParentWindow(), pnlStipends);

            // creates a compound manager for it
            CompoundDataPanelsManager compoundDataPanelsManager=new CompoundDataPanelsManager();
            compoundDataPanelsManager.setPanels(panelsStipend);
            compoundDataPanelsManager.setMandatory(false);
            
            pnlStipends.add(compoundDataPanelsManager);
            compoundDataPanelsManager.display();
            
        }
        getParentWindow().pack();
    }

    // readjusting the default values to a new size
    private void readjustDefaultValues() {
        if ((!yearsPanel.isValid()) || (yearsPanel.getEdittedValue().equals(""))) {
            defaultDirectMoney=new Long[0];
            defaultIndirectMoney=new Long[0];
        }
        else {
            defaultYears=Integer.parseInt(yearsPanel.getEdittedValue());
            Long[] oldDefaultDirectMoney=defaultDirectMoney;
            Long[] oldDefaultIndirectMoney=defaultIndirectMoney;
            defaultDirectMoney=new Long[defaultYears];
            defaultIndirectMoney=new Long[defaultYears];
            for (int i=0;i<defaultYears;i++) {
                if (i<oldDefaultDirectMoney.length) {
                    defaultDirectMoney[i]=oldDefaultDirectMoney[i];
                    defaultIndirectMoney[i]=oldDefaultIndirectMoney[i];
                } else {
                    defaultDirectMoney[i]=null;
                    defaultIndirectMoney[i]=null;
                }
            }
        }
    }
    
    
    // retreives whether the panel is valid: if the year is valid and each yearly panel is valid
    @Override
    public boolean isValid() {
        boolean allValid=true;
        if (!yearsPanel.isValid()) {
            allValid=false;
        }
        
        for (int i = 0; i < panelsPerennialStipends.length; i++) {
            PanelsStipend panelsStipend = panelsPerennialStipends[i];
            if (!panelsStipend.isValid()) {
                allValid=false;
            }
        }
        return(allValid);
    }
    

    // Saves a new PerennialStipends from the current values
    @Override
    public void saveData() {
        int newPerennialStipendsId=0;
        try {

            Connection conn=Db.openDbConnection();
            PreparedStatement createPerennialStipendsStatement = Db.createPreparedStatement(conn, "INSERT INTO tblPerennialStipends (YearsRef) VALUES (?)");


            ////////////////////////////////////
            // Save all different data pieces
            ////////////////////////////////////

            // Saves the years
            int newLoggedYearsId = MyDialog.saveLoggedDataPanelsManagerData(yearsView);
            // Saves the PerennialStipends
            createPerennialStipendsStatement.setInt(1, newLoggedYearsId);
            createPerennialStipendsStatement.executeUpdate();

            newPerennialStipendsId = Db.getLastIdentity();
            createPerennialStipendsStatement.close();
            Db.closeDbConnection(conn);
            
            // saves all different years' panels' data as well
            for (int i = 0; i < panelsPerennialStipends.length; i++) {
                PanelsStipend panelsStipend = panelsPerennialStipends[i];
                // tell each panel what is the newly created id
                panelsStipend.setDefaultPerennialStipendsId(newPerennialStipendsId);
                panelsStipend.saveData();
            }
        } catch (SQLException ex) {
            Logger.getLogger(PanelsPerennialStipends.class.getName()).log(Level.SEVERE, null, ex);
        }
        perennialStipends=PerennialStipends.getByID(newPerennialStipendsId);
    }

    // returns the wrapped PerennialStipends - Used after saving a new PerennialStipends
    public PerennialStipends getPerennialStipends() {
        return(perennialStipends);
    }
}
